import * as Cesium from 'cesium';

/**
 * 台风工具类，用于处理台风数据和绘制台风相关要素
 */
export class TyphoonUtils {
  constructor(viewer) {
    this.viewer = viewer;
    this.typhoonEntities = []; // 存储所有台风相关实体
    this.typhoonData = null;
    
    // 动画状态
    this.currentPointIndex = 0;
    this.animationTimer = null;
    this.animationSpeed = 1000; // 每个点的动画间隔（毫秒）
    this.isAnimating = false;
    
    // 台风等级颜色映射
    this.typhoonLevelColors = {
      '热带低压': Cesium.Color.GREEN,
      '热带风暴': Cesium.Color.BLUE,
      '强热带风暴': Cesium.Color.YELLOW,
      '台风': Cesium.Color.ORANGE,
      '强台风': Cesium.Color.PINK,
      '超强台风': Cesium.Color.RED
    };
    
    // 预报台颜色映射
    this.forecastColors = {
      '中国': Cesium.Color.RED,
      '中国香港': Cesium.Color.ORANGE,
      '日本': Cesium.Color.GREEN,
      '中国台湾': Cesium.Color.PURPLE,
      '美国': Cesium.Color.CYAN
    };
    
    // 预报台线型映射
    this.forecastLineStyles = {
      '中国': new Cesium.PolylineDashMaterialProperty({ color: Cesium.Color.RED, dashLength: 10 }),
      '中国香港': new Cesium.PolylineDashMaterialProperty({ color: Cesium.Color.ORANGE, dashLength: 10, gapLength: 5 }),
      '日本': new Cesium.PolylineDashMaterialProperty({ color: Cesium.Color.GREEN, dashLength: 15, gapLength: 3 }),
      '中国台湾': new Cesium.PolylineDashMaterialProperty({ color: Cesium.Color.PURPLE, dashLength: 8, gapLength: 8 }),
      '美国': new Cesium.PolylineDashMaterialProperty({ color: Cesium.Color.CYAN, dashLength: 12, gapLength: 6 })
    };
    
    // 降雨等级颜色映射
    this.rainfallColors = {
      '0-10': Cesium.Color.GREEN.withAlpha(0.5),
      '10-25': Cesium.Color.LIME.withAlpha(0.5),
      '25-50': Cesium.Color.YELLOW.withAlpha(0.5),
      '50-100': Cesium.Color.ORANGE.withAlpha(0.5),
      '100-250': Cesium.Color.RED.withAlpha(0.5),
      '>250': Cesium.Color.MAGENTA.withAlpha(0.5)
    };

    // GIF 动画支持：共享 Image 与定时刷新句柄
    this._typhoonGifUrl = new URL('../assets/img/typhoon.gif', import.meta.url).href;
    this._typhoonGifImage = null;
    this._typhoonGifTimer = null;
    
    // 鼠标事件处理
    this.mouseHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    this.currentPopup = null;
    this.setupMouseEvents();
  }
  
  /**
   * 设置鼠标事件监听
   */
  setupMouseEvents() {
    // 鼠标移动事件，用于显示弹窗
    this.mouseHandler.setInputAction((movement) => {
      const pickedObject = this.viewer.scene.pick(movement.endPosition);
      
      if (Cesium.defined(pickedObject) && pickedObject.id && pickedObject.id.typhoonPointData) {
        // 显示弹窗
        this.showPopup(pickedObject.id.typhoonPointData, movement.endPosition);
      } else {
        // 隐藏弹窗
        this.hidePopup();
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }
  
  /**
   * 显示弹窗
   * @param {Object} pointData - 台风点数据
   * @param {Cesium.Cartesian2} position - 屏幕坐标
   */
  showPopup(pointData, position) {
    // 解析半径数据
    const radius7 = pointData.radius7 ? pointData.radius7.split('|').map(Number).join('|') : '--';
    const radius10 = pointData.radius10 ? pointData.radius10.split('|').map(Number).join('|') : '--';
    const radius12 = pointData.radius12 ? pointData.radius12.split('|').map(Number).join('|') : '--';
    
    // 创建详细信息HTML，采用系统统一的UI风格
    const html = `
      <div style="
        background: linear-gradient(135deg, rgba(15, 23, 42, 0.15) 0%, rgba(30, 41, 59, 0.15) 100%);
        
        border: 1px solid rgba(255, 255, 255, 0.15);
        border-radius: 10px;
        padding: 12px;
        color: rgba(255, 255, 255, 0.95);
        font-family: sans-serif;
        box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
      ">
        <h3 style="
          margin: 0 0 12px 0;
          color: white;
          font-size: 16px;
          font-weight: 600;
          letter-spacing: 0.5px;
          padding-bottom: 10px;
          border-bottom: 1px solid rgba(255, 255, 255, 0.15);
        ">${this.typhoonData.name}(${this.typhoonData.enname})<br/> ${pointData.time}</h3>
        <div style="
          display: flex;
          flex-direction: column;
          gap: 8px;
          font-size: 12px;
        ">
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">中心位置:</span>
            <span style="font-weight: 500;">${pointData.lng}° / ${pointData.lat}°</span>
          </div>
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">风速风力:</span>
            <span style="font-weight: 500;">${pointData.speed}米/秒，${pointData.power}级(${pointData.strong})</span>
          </div>
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">中心气压:</span>
            <span style="font-weight: 500;">${pointData.pressure}百帕</span>
          </div>
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">移速移向:</span>
            <span style="font-weight: 500;">${pointData.movespeed}公里/小时，${pointData.movedirection}</span>
          </div>
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">七级半径:</span>
            <span style="font-weight: 500;letter-spacing: 2px;">${radius7}</span>
          </div>
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">十级半径:</span>
            <span style="font-weight: 500;letter-spacing: 2px;">${radius10}</span>
          </div>
          <div style="display: flex; justify-content: space-between;">
            <span style="color: rgba(255, 255, 255, 0.7);">十二级半径:</span>
            <span style="font-weight: 500;letter-spacing: 2px;">${radius12}</span>
          </div>
        </div>
      </div>
    `;
    
    // 隐藏已有的弹窗
    this.hidePopup();
    
    // 创建自定义弹窗元素
    this.currentPopup = document.createElement('div');
    this.currentPopup.innerHTML = html;
    this.currentPopup.style.cssText = `
      position: absolute;
      left: ${position.x + 10}px;
      top: ${position.y + 10}px;
      width: 300px;
      height: auto;
      z-index: 10000;
      pointer-events: none;
      transform: translateY(-5px);
      opacity: 0;
      transition: all 0.3s ease;
    `;
    
    // 添加到Cesium容器中
    const cesiumContainer = document.getElementById('cesiumContainer');
    if (cesiumContainer) {
      cesiumContainer.appendChild(this.currentPopup);
      
      // 添加动画效果
      setTimeout(() => {
        if (this.currentPopup) {
          this.currentPopup.style.transform = 'translateY(0)';
          this.currentPopup.style.opacity = '1';
        }
      }, 10);
    }
  }
  
  /**
   * 隐藏弹窗
   */
  hidePopup() {
    if (this.currentPopup && this.currentPopup.parentNode) {
      this.currentPopup.parentNode.removeChild(this.currentPopup);
      this.currentPopup = null;
    }
  }
  
  /**
   * 加载台风数据
   * @param {Object} data - 台风数据
   */
  loadTyphoonData(data) {
    this.typhoonData = data;
  }
  
  /**
   * 绘制风圈
   * @param {Object} point - 台风点数据
   */
  drawWindCircle(point) {
    if (!point.radius7 && !point.radius10 && !point.radius12) return;
    
    const center = Cesium.Cartesian3.fromDegrees(parseFloat(point.lng), parseFloat(point.lat));
    
    // 绘制7级风圈
    if (point.radius7) {
      const radius7 = point.radius7.split('|').map(Number);
      this.drawIrregularWindCircle(center, radius7, Cesium.Color.BLUE.withAlpha(0.3), 1);
    }
    
    // 绘制10级风圈
    if (point.radius10) {
      const radius10 = point.radius10.split('|').map(Number);
      this.drawIrregularWindCircle(center, radius10, Cesium.Color.YELLOW.withAlpha(0.4), 1);
    }
    
    // 绘制12级风圈
    if (point.radius12) {
      const radius12 = point.radius12.split('|').map(Number);
      this.drawIrregularWindCircle(center, radius12, Cesium.Color.RED.withAlpha(0.5), 1);
    }
  }
  
  /**
   * 绘制圆形
   * @param {Cesium.Cartesian3} center - 圆心
   * @param {number} radius - 半径（米）
   * @param {Cesium.Color} color - 颜色
   * @param {number} width - 线宽
   */
  drawCircle(center, radius, color, width) {
    const entity = this.viewer.entities.add({
      position: center,
      ellipse: {
        semiMajorAxis: radius,
        semiMinorAxis: radius,
        material: color,
        outline: true,
        outlineColor: color.withAlpha(0.8),
        outlineWidth: width
      }
    });
    this.typhoonEntities.push(entity);
  }
  
  /**
   * 绘制不规则风圈
   * @param {Cesium.Cartesian3} center - 圆心
   * @param {Array} radii - 四个方向的半径 [东, 北, 西, 南]（公里）
   * @param {Cesium.Color} color - 颜色
   * @param {number} width - 线宽
   */
  drawIrregularWindCircle(center, radii, color, width) {
    if (!radii || radii.length < 4) return;
    
    // 获取中心点的经纬度
    const cartographic = Cesium.Cartographic.fromCartesian(center);
    const centerLng = Cesium.Math.toDegrees(cartographic.longitude);
    const centerLat = Cesium.Math.toDegrees(cartographic.latitude);
    
    // 创建点对象
    const pointObj = {
      lng: centerLng,
      lat: centerLat
    };
    
    // 创建多边形顶点
    const positions = [];
    const radiusList = radii.map(r => r / 100); // 将公里转换为度
    const startAngleList = [0, 90, 180, 270]; // 四个方向的起始角度
    let fx, fy;
    
    startAngleList.forEach((startAngle, index) => {
      const radius = radiusList[index];
      const pointNum = 90; // 每个方向生成90个点
      const endAngle = startAngle + 90;
      
      for (let i = 0; i <= pointNum; i++) {
        const angle = startAngle + ((endAngle - startAngle) * i) / pointNum;
        const sin = Math.sin((angle * Math.PI) / 180);
        const cos = Math.cos((angle * Math.PI) / 180);
        
        // 计算当前顶点的经纬度
        const x = centerLng + radius * sin;
        const y = centerLat + radius * cos;
        
        positions.push(Cesium.Cartesian3.fromDegrees(x, y));
        
        // 记录第一个点，用于闭合多边形
        if (startAngle === 0 && i === 0) {
          fx = x;
          fy = y;
        }
      }
    });
    
    // 闭合多边形
    positions.push(Cesium.Cartesian3.fromDegrees(fx, fy));
    
    // 创建多边形实体
    const entity = this.viewer.entities.add({
      polygon: {
        hierarchy: new Cesium.PolygonHierarchy(positions),
        material: color,
        outline: true,
        outlineColor: color.withAlpha(0.8),
        outlineWidth: width,
        height: 0,
        extrudedHeight: 0
      }
    });
    
    this.typhoonEntities.push(entity);
  }
  
  /**
   * 标记登陆点
   * @param {Object} land - 登陆点数据
   */
  drawLandPoint(land) {
    const position = Cesium.Cartesian3.fromDegrees(parseFloat(land.lng), parseFloat(land.lat));
    
    const entity = this.viewer.entities.add({
      position: position,
      point: {
        pixelSize: 10,
        color: Cesium.Color.RED,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2
      },
      label: {
        text: `${land.landaddress}\n${land.landtime}`,
        font: 'bold 14px sans-serif',
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 3,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(0, -15),
        showBackground: true,
        backgroundColor: Cesium.Color.BLACK.withAlpha(0.75),
        backgroundPadding: new Cesium.Cartesian2(6, 4),
        // 禁用深度测试距离，确保标签在复杂地形上也能清晰可见
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      }
    });
    this.typhoonEntities.push(entity);
  }
  
  /**
   * 绘制预报台路径
   * @param {Object} forecast - 预报台数据
   */
  drawForecastPath(forecast) {
    const points = forecast.forecastpoints;
    if (!points || points.length < 2) return;
    
    const positions = points.map(point => {
      return Cesium.Cartesian3.fromDegrees(parseFloat(point.lng), parseFloat(point.lat));
    });
    
    const color = this.forecastColors[forecast.tm] || Cesium.Color.WHITE;
    const lineStyle = this.forecastLineStyles[forecast.tm] || new Cesium.PolylineDashMaterialProperty({ color });
    
    const entity = this.viewer.entities.add({
      polyline: {
        positions: positions,
        width: 3,
        material: lineStyle,
        clampToGround: false
      },
      name: `${forecast.tm}预报路径`
    });
    this.typhoonEntities.push(entity);
  }
  
  /**
   * 绘制台风中心路径
   */
  drawTyphoonPath() {
    if (!this.typhoonData || !this.typhoonData.points || this.typhoonData.points.length < 2) return;
    
    const positions = this.typhoonData.points.map(point => {
      return Cesium.Cartesian3.fromDegrees(parseFloat(point.lng), parseFloat(point.lat));
    });
    
    const entity = this.viewer.entities.add({
      polyline: {
        positions: positions,
        width: 4,
        material: Cesium.Color.RED,
        clampToGround: false
      },
      name: `${this.typhoonData.name}路径`
    });
    this.typhoonEntities.push(entity);
  }
  
  /**
   * 绘制台风中心标记
   */
  drawTyphoonCenter() {
    if (!this.typhoonData || !this.typhoonData.points) return;
    
    // 绘制每个时间点的台风中心，只绘制点，不绘制标签
    this.typhoonData.points.forEach(point => {
      const position = Cesium.Cartesian3.fromDegrees(parseFloat(point.lng), parseFloat(point.lat));
      const color = this.typhoonLevelColors[point.strong] || Cesium.Color.WHITE;
      
      const entity = this.viewer.entities.add({
        position: position,
        point: {
          pixelSize: 12,
          color: color,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 2
        },
        // 添加自定义属性，用于鼠标事件识别
        typhoonPointData: point,
        // 不显示默认标签
        label: {
          show: false
        }
      });
      this.typhoonEntities.push(entity);
    });
  }
  
  /**
   * 绘制警戒线
   */
  drawWarningLines() {
    // 24小时警戒线
    const entity24 = this.viewer.entities.add({
      name: '24',
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([
          127, 34,
          127, 22,
          119, 18,
          119, 11,
          113, 4.5,
          105, 0
        ]),
        width: 2,
        material: Cesium.Color.RED,
        clampToGround: true,
      }
    });
    this.typhoonEntities.push(entity24);
    
    // 48小时警戒线
    const entity48 = this.viewer.entities.add({
      name: '48',
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([
          132, 34,
          132, 22,
          119, 0,
          105, 0
        ]),
        width: 2,
        material: Cesium.Color.YELLOW,
        clampToGround: true,
      }
    });
    this.typhoonEntities.push(entity48);
    
    // 24小时警戒线标签
    const label24 = this.viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(126.129019, 29.104287),
      label: {
        text: '24小时警戒线',
        font: '14pt monospace',
        fillColor: Cesium.Color.RED,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        backgroundColor: Cesium.Color.BLACK.withAlpha(0.6),
        backgroundPadding: new Cesium.Cartesian2(6, 4),
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      }
    });
    this.typhoonEntities.push(label24);
    
    // 48小时警戒线标签
    const label48 = this.viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(132, 20),
      label: {
        text: '48小时警戒线',
        font: '14pt monospace',
        fillColor: Cesium.Color.YELLOW,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        backgroundColor: Cesium.Color.BLACK.withAlpha(0.6),
        backgroundPadding: new Cesium.Cartesian2(6, 4),
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      }
    });
    this.typhoonEntities.push(label48);
  }
  
  /**
   * 绘制台风GIF图标
   */
  drawTyphoonIcon() {
    if (!this.typhoonData || !this.typhoonData.points || this.typhoonData.points.length === 0) return;
    
    const latestPoint = this.typhoonData.points[this.typhoonData.points.length - 1];
    const position = Cesium.Cartesian3.fromDegrees(parseFloat(latestPoint.lng), parseFloat(latestPoint.lat), 10000);
    
    // 使用共享 Image 加载 GIF（可动画），并将其作为 billboard.image
    if (!this._typhoonGifImage) {
      this._typhoonGifImage = new Image();
      this._typhoonGifImage.crossOrigin = 'anonymous';
      this._typhoonGifImage.src = this._typhoonGifUrl;
    }

    const entity = this.viewer.entities.add({
      position: position,
      billboard: {
        image: this._typhoonGifImage,
        scale: 0.5,
        width: 64,
        height: 64,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER
      }
    });
    this.typhoonEntities.push(entity);

    // 启动 GIF 刷新器（如果尚未启动）——定期重新赋值 billboard.image 并请求渲染，强制更新 WebGL 纹理
    if (!this._typhoonGifTimer) {
      this._typhoonGifTimer = setInterval(() => {
        try {
          // 重新赋值所有带 billboard 的实体的 image 引用
          for (let e of this.typhoonEntities) {
            if (e && e.billboard) {
              e.billboard.image = this._typhoonGifImage;
            }
          }
          // 请求一次渲染以确保纹理刷帧
          if (this.viewer && this.viewer.scene) this.viewer.scene.requestRender();
        } catch (err) {
          // 忽略错误
        }
      }, 200); // 200ms 刷新一次，权衡性能与帧率
    }
  }
  

  
  /**
   * 定位到台风位置
   */
  zoomToTyphoon() {
    if (!this.typhoonData || !this.typhoonData.points) return;
    
    const latestPoint = this.typhoonData.points[this.typhoonData.points.length - 1];
    const position = Cesium.Cartesian3.fromDegrees(parseFloat(latestPoint.lng), parseFloat(latestPoint.lat), 1000000);
    
    this.viewer.camera.setView({
      destination: position,
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90), // 垂直向下
        roll: 0
      }
    });
  }
  
  /**
   * 清除所有台风实体
   */
  clearTyphoon() {
    this.typhoonEntities.forEach(entity => {
      this.viewer.entities.remove(entity);
    });
    this.typhoonEntities = [];
    // 停止 GIF 刷新计时器并释放引用
    try {
      if (this._typhoonGifTimer) {
        clearInterval(this._typhoonGifTimer);
        this._typhoonGifTimer = null;
      }
    } catch (e) {}
    this._typhoonGifImage = null;
  }
  
  /**
   * 加载台风数据
   * @param {Object} data - 台风数据
   */
  setTyphoonData(data) {
    this.typhoonData = data;
  }
  
  /**
   * 获取台风等级颜色
   * @param {string} level - 台风等级
   * @returns {Cesium.Color} 对应的颜色
   */
  getTyphoonLevelColor(level) {
    return this.typhoonLevelColors[level] || Cesium.Color.WHITE;
  }
  
  /**
   * 获取预报台颜色
   * @param {string} name - 预报台名称
   * @returns {Cesium.Color} 对应的颜色
   */
  getForecastColor(name) {
    return this.forecastColors[name] || Cesium.Color.WHITE;
  }
  
  /**
   * 开始台风动画
   * @param {number} speed - 动画速度（毫秒/点）
   */
  startAnimation(speed = 1000) {
    if (!this.typhoonData || !this.typhoonData.points || this.typhoonData.points.length === 0) return;
    
    this.animationSpeed = speed;
    this.isAnimating = true;
    this.animate();
  }
  
  /**
   * 暂停台风动画
   */
  pauseAnimation() {
    this.isAnimating = false;
    if (this.animationTimer) {
      clearTimeout(this.animationTimer);
      this.animationTimer = null;
    }
  }
  
  /**
   * 重置台风动画
   */
  resetAnimation() {
    this.pauseAnimation();
    this.currentPointIndex = 0;
    this.updateCurrentTyphoonState();
  }
  
  /**
   * 动画循环
   */
  animate() {
    if (!this.isAnimating || !this.typhoonData || !this.typhoonData.points) return;
    
    // 更新当前台风状态
    this.updateCurrentTyphoonState();
    
    // 自动调整相机视角
    this.updateCameraView();
    
    // 移动到下一个点
    this.currentPointIndex++;
    
    // 如果到达最后一个点，重置索引
    if (this.currentPointIndex >= this.typhoonData.points.length) {
      this.currentPointIndex = 0;
    }
    
    // 设置下一次动画
    this.animationTimer = setTimeout(() => {
      this.animate();
    }, this.animationSpeed);
  }
  
  /**
   * 更新当前台风状态
   */
  updateCurrentTyphoonState() {
    if (!this.typhoonData || !this.typhoonData.points) return;
    
    // 获取当前点
    const currentPoint = this.typhoonData.points[this.currentPointIndex];
    
    // 清除当前台风实体
    this.clearCurrentTyphoonEntities();
    
    // 同时绘制风圈和GIF图标，减少闪烁
    this.drawWindCircle(currentPoint);
    this.drawCurrentTyphoonIcon(currentPoint);
  }
  
  /**
   * 清除当前台风实体
   */
  clearCurrentTyphoonEntities() {
    // 只清除风圈和台风图标，保留其他实体
    const entitiesToRemove = [];
    this.typhoonEntities.forEach(entity => {
      // 检查实体是否有风圈（polygon或ellipse）或台风图标（billboard）
      if (entity.polygon || entity.ellipse || entity.billboard) {
        entitiesToRemove.push(entity);
      }
    });
    
    entitiesToRemove.forEach(entity => {
      this.viewer.entities.remove(entity);
      const index = this.typhoonEntities.indexOf(entity);
      if (index > -1) {
        this.typhoonEntities.splice(index, 1);
      }
    });

    // 如果没有剩余任何 billboard 实体，则停止 GIF 刷新计时器
    const hasBillboard = this.typhoonEntities.some(e => e && e.billboard);
    if (!hasBillboard && this._typhoonGifTimer) {
      try { clearInterval(this._typhoonGifTimer); } catch (e) {}
      this._typhoonGifTimer = null;
      this._typhoonGifImage = null;
    }
  }
  
  /**
   * 绘制当前点的台风GIF图标
   * @param {Object} point - 当前台风点数据
   */
  drawCurrentTyphoonIcon(point) {
    if (!point) return;
    
    const position = Cesium.Cartesian3.fromDegrees(parseFloat(point.lng), parseFloat(point.lat), 10000);
    // 使用共享 GIF Image
    if (!this._typhoonGifImage) {
      this._typhoonGifImage = new Image();
      this._typhoonGifImage.crossOrigin = 'anonymous';
      this._typhoonGifImage.src = this._typhoonGifUrl;
    }

    const entity = this.viewer.entities.add({
      position: position,
      billboard: {
        image: this._typhoonGifImage,
        scale: 0.5,
        width: 64,
        height: 64,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER
      },
      label: {
        text: `${this.typhoonData.name} (${this.typhoonData.enname})\n${point.time}\n${point.strong}`,
        font: '14px sans-serif',
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(0, -35),
        backgroundColor: Cesium.Color.BLACK.withAlpha(0.6)
      }
    });
    this.typhoonEntities.push(entity);

    // 启动 GIF 刷新器（如果尚未启动）
    if (!this._typhoonGifTimer) {
      this._typhoonGifTimer = setInterval(() => {
        try {
          for (let e of this.typhoonEntities) {
            if (e && e.billboard) {
              e.billboard.image = this._typhoonGifImage;
            }
          }
          if (this.viewer && this.viewer.scene) this.viewer.scene.requestRender();
        } catch (err) {}
      }, 200);
    }
  }
  
  /**
   * 更新相机视角
   */
  updateCameraView() {
    if (!this.typhoonData || !this.typhoonData.points) return;
    
    const currentPoint = this.typhoonData.points[this.currentPointIndex];
    // 降低相机高度，确保能看到GIF和风圈
    const position = Cesium.Cartesian3.fromDegrees(parseFloat(currentPoint.lng), parseFloat(currentPoint.lat), 1500000);
    
    this.viewer.camera.setView({
      destination: position,
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90), // 垂直向下视角
        roll: 0
      },
      duration: this.animationSpeed / 100 // 平滑过渡
    });
  }
  
  /**
   * 绘制所有台风要素
   * @param {Object} options - 显示选项
   * @param {boolean} options.showWindCircle - 是否显示风圈
   * @param {boolean} options.showLandPoints - 是否显示登陆点
   * @param {boolean} options.showForecastPaths - 是否显示预报路径
   * @param {boolean} options.showTyphoonPath - 是否显示台风路径
   * @param {boolean} options.showTyphoonCenter - 是否显示台风中心
   * @param {boolean} options.showTyphoonIcon - 是否显示台风图标
   * @param {boolean} options.animate - 是否启动动画
   * @param {number} options.animationSpeed - 动画速度（毫秒/点）
   */
  drawTyphoon(options = {}) {
    if (!this.typhoonData) return;
    
    // 清除现有实体
    this.clearTyphoon();
    
    const { 
      showWindCircle = true, 
      showLandPoints = true, 
      showForecastPaths = true,
      showTyphoonPath = true,
      showTyphoonCenter = true,
      showTyphoonIcon = true,
      animate = false,
      animationSpeed = 1000
    } = options;
    
    // 绘制台风路径
    if (showTyphoonPath) {
      this.drawTyphoonPath();
    }
    
    // 绘制台风中心
    if (showTyphoonCenter) {
      this.drawTyphoonCenter();
    }
    
    // 绘制登陆点
    if (showLandPoints && this.typhoonData.land) {
      this.typhoonData.land.forEach(land => {
        this.drawLandPoint(land);
      });
    }
    
    // 绘制预报路径 - 只绘制最后一个点的预报路径
    if (showForecastPaths) {
      const lastPoint = this.typhoonData.points[this.typhoonData.points.length - 1];
      if (lastPoint.forecast) {
        lastPoint.forecast.forEach(forecast => {
          this.drawForecastPath(forecast);
        });
      }
    }
    
    // 绘制警戒线
    this.drawWarningLines();
    
    // 如果需要动画，启动动画
    if (animate) {
      this.startAnimation(animationSpeed);
    } else {
      // 否则绘制当前点的状态
      this.updateCurrentTyphoonState();
    }
    
    // 定位到台风位置
    this.zoomToTyphoon();
  }
}